import os
import sys
import pygame
from player import *
# Set up screen
SCREEN_WIDTH = 500
SCREEN_HEIGHT = 600
PLAYER_HEIGHT = 60
FONT_HEIGHT = 12


def my_quit(player):
    player.quit()
    pygame.quit()
    quit()
    sys.exit(0)


class Item(pygame.sprite.Sprite):
    """ This class represents the bullet . """
    def __init__(self, fdtype, index, path, text, font):
        # Call the parent class (Sprite) constructor
        super().__init__()

        self.fdtype = fdtype
        self.index = index
        self.path = path
        self.text = text
        self.font = font
        self.org_y = index * (FONT_HEIGHT + 2) + PLAYER_HEIGHT
        self.flag = False
        self.select = False
        self.images = [font.render(text, True, (32, 32, 32)),
                       font.render(text, True, (32, 32, 255)),
                       font.render(text, True, (255, 32, 32))]
        self.image = self.images[0]
        rc = self.image.get_rect()
        rc.y = self.org_y
        rc.width = SCREEN_WIDTH
        self.rect = rc

    def get_path(self):
        return self.path

    def get_text(self):
        return self.text

    def get_full_path(self):
        return self.path + os.sep + self.text

    def get_type(self):
        return self.fdtype

    def set_select(self, select):
        if select is not self.select:
            if select:
                self.image = self.images[2]
            else:
                self.image = self.images[0]
            self.select = select

    def update(self, pos):
        if self.rect.collidepoint(pos):
            self.image = self.images[1]
            return self
        else:
            if self.select:
                self.image = self.images[2]
                return None
            else:
                self.image = self.images[0]
                return None

    def roll(self, delta):
        if delta > 0:
            if self.rect.y >= self.org_y:
                return
        self.rect.y += delta

    def draw(self, screen):
        if self.rect.y >= PLAYER_HEIGHT:
            screen.blit(self.image, self.rect)

'''
class FileListBox(object):
    list = []
    cur_path = '.'
    DIR = 0
    FILE = 1
    font = None

    def __init__(self, path='.', font=None):
        if font is None:
            font = pygame.font.Font(None, 12)
        self.font = font
        self.cd(path)

    def cd(self, path):
        self.cur_path = path
        dl, fl = self._get_fd_list()
        self._make_list(dl, fl)

    def _make_list(self, dl, fl):

        self.list = pygame.sprite.Group()
        for itm in dl:
            self.list.add(FileItem(self.DIR, len(self.list), itm, self.font))

        for itm in fl:
            self.list.add(FileItem(self.FILE, len(self.list), itm, self.font))

    def _get_fd_list(self):
        for (path, dir_names, file_names) in os.walk(self.cur_path):
            dir_names.sort()
            file_names.sort()
            return dir_names, file_names
'''


class Button(pygame.sprite.Sprite):
    """ This class represents the bullet . """
    def __init__(self, font, pos, text='', image='skin/button-white.png'):
        # Call the parent class (Sprite) constructor
        super().__init__()

        self.text = text
        self.flag = False
        self.select = False

        if len(text) > 0:
            t1 = font.render(text, True, (32, 32, 32))
            w, h = t1.get_size()
            self.bg = pygame.image.load(image).convert()
            self.bg = pygame.transform.smoothscale(self.bg, (w, h))
            self.images = [self.bg, self.bg, self.bg]
            self.images[0].blit(t1, t1.get_rect())
            t2 = font.render(text, True, (32, 32, 255))
            self.images[1].blit(t2, t2.get_rect())
            t3 = font.render(text, True, (255, 32, 32))
            self.images[2].blit(t3, t3.get_rect())
        else:
            self.bg = pygame.image.load(image).convert_alpha()
            self.bg = pygame.transform.smoothscale(self.bg, (20, 20))
            self.images = [self.bg, self.bg, self.bg]

        self.image = self.images[0]
        rc = self.image.get_rect()
        rc.x = pos[0]
        rc.y = pos[1]
        self.rect = rc

    def get_text(self):
        return self.text

    def set_select(self, select):
        if select is not self.select:
            if select:
                self.image = self.images[2]
            else:
                self.image = self.images[0]
            self.select = select

    def update(self, pos):
        if self.rect.collidepoint(pos):
            self.image = self.images[1]
        else:
            if self.select:
                self.image = self.images[2]
            else:
                self.image = self.images[0]

    def roll(self, delta):
        if delta > 0:
            if self.rect.y >= self.org_y:
                return
        self.rect.y += delta

    def draw(self, screen):
        if self.rect.y >= PLAYER_HEIGHT:
            screen.blit(self.image, self.rect)


class Mouse(pygame.sprite.Sprite):
    def __init__(self):
        # Call the parent class (Sprite) constructor
        super().__init__()
        self.image = pygame.Surface((1, 1))
        self.image.convert()
        self.rect = self.image.get_rect()

    def update(self):
        pos = pygame.mouse.get_pos()
        self.rect.x = pos[0] - self.rect.width // 2
        self.rect.y = pos[1] - self.rect.height // 2  # - PLAYER_HEIGHT


def get_dir_file_list(path):
    # all_list = []
    for (path, dir_names, file_names) in os.walk(path):
        dir_names.sort()
        file_names.sort()
        return dir_names, file_names


def generate_sprite_list(path, font):
    print("get_dir_file_list("+path+")")
    dl, fl = get_dir_file_list(path)

    sg = pygame.sprite.Group()
    for itm in dl:
        sg.add(Item(0, len(sg), path, itm, font))

    for itm in fl:
        sg.add(Item(1, len(sg), path, itm, font))
    return sg


def get_select(m, l, over=True, select=False):
    block_hit_list = pygame.sprite.spritecollide(m, l, False)
    if len(block_hit_list):
        sel = block_hit_list[0]
        if over:
            sel.set_over(True)
        if select:
            sel.set_select(True)
    else:
        sel = None
    return sel


def get_play_text(font, play_item):
    return font.render(play_item.get_text(), True, (32, 32, 32))


def main():
    # Initialize Pygame
    pygame.init()

    player = mplayer.MPlayer()
    player.start()

    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('PyGame MP3 Player')  # Set the window bar title

    # Set up font
    font = pygame.font.Font("/home/cain76/.fonts/LexiGulim090423.ttf", FONT_HEIGHT)

    # Set up clock
    clock = pygame.time.Clock()
    FPS = 10

#    list_surface = screen.copy().convert_alpha()

    mouse = Mouse()

    path = "/media/06Tera1/Music/00 차트"
    df_sprite_list = generate_sprite_list(path, font)
    over_item = None
    play_item = None
    play_text = None
    buttons = pygame.sprite.Group()
    buttons.add(Button(text='PL', font=font, pos=(450, 30)))
    buttons.add(Button(text='FL', font=font, pos=(400, 30)))
    buttons.add(Button(image='skin/outline/play.png', font=font, pos=(10, 22)))
    buttons.add(Button(image='skin/outline/pause.png', font=font, pos=(30, 22)))
    buttons.add(Button(image='skin/outline/stop.png', font=font, pos=(50, 22)))
    buttons.add(Button(image='skin/outline/prev.png', font=font, pos=(70, 22)))
    buttons.add(Button(image='skin/outline/next.png', font=font, pos=(90, 22)))

    while True:  # for each frame
        clock.tick(FPS)
        screen.fill((255, 255, 255), (0, 0, SCREEN_WIDTH, 60))
        screen.fill((225, 225, 225), (0, PLAYER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                my_quit(player)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    my_quit(player)
                elif event.key == pygame.K_SPACE:
                    player.play()
            elif event.type == pygame.MOUSEMOTION:
                mouse.update()
                buttons.update(pygame.mouse.get_pos())
                df_sprite_list.update(pygame.mouse.get_pos())
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    items = pygame.sprite.spritecollide(mouse, df_sprite_list, False)
                    if len(items) > 0:
                        over_item = items[0]
                    else:
                        over_item = None
                    if over_item:
                        print(over_item.get_text())
                        if over_item.get_type() == 0:
                            path = over_item.get_full_path()
                            over_item = None
                            df_sprite_list = generate_sprite_list(path, font)
                        else:
                            if play_item is not None:
                                play_item.set_select(False)
                            play_item = over_item
                            if play_item is not None:
                                play_item.set_select(True)
                                play_text = get_play_text(font, play_item)
                                player.stop()
                                player.load(play_item.get_full_path())
                                player.play()
                elif event.button == 3:
                    path, t = os.path.split(path)
                    df_sprite_list = generate_sprite_list(path, font)
                elif event.button == 4:
                    for itm in df_sprite_list:
                        itm.roll(FONT_HEIGHT)
                elif event.button == 5:
                    for itm in df_sprite_list:
                        itm.roll(-FONT_HEIGHT)

        buttons.draw(screen)
        # df_sprite_list.draw(screen)
        for spr in df_sprite_list:
            if spr.rect.y < SCREEN_HEIGHT:
                spr.draw(screen)
#        df_sprite_list.draw(list_surface)
#        screen.blit(list_surface, (0, PLAYER_HEIGHT))

        if play_item is not None:
            screen.blit(play_text, (5, 5))

        if player.is_playing() and player.get_total_seconds() > 0:
            pos = SCREEN_WIDTH*player.get_current_seconds() / player.get_total_seconds()
            pygame.draw.rect(screen, (255, 0, 0), (0, 50, int(round(pos)), 10))

        pygame.display.flip()

main()
